﻿using System;
using System.Net;
using UnityEngine;
using UnityEngine.Profiling;
using Yoozoo.Framework.Core;
using Yoozoo.Framework.Managers;
using Yoozoo.Gta.Common;
using Yoozoo.Mars.Got.Timer;

namespace Yoozoo.Manager
{
    public class IcmpPingPlugin:Singleton<IcmpPingPlugin>
    {
        private const float m_pingSendRate = 10;
        private DateTime m_lastTime = DateTime.MinValue;
        private string serverIp;
        private Ping _pinger;
        private int checkpingInteval;
        private float overTime = 5;
        private int maxRePingNum = 2;
        private string serverAddress;

        public void UpdateServerIp(string addr)
        {
            serverAddress = addr;
            try
            {
                IPAddress[] ips = Dns.GetHostAddresses(serverAddress);
                serverIp = (ips[0]).ToString();
            }
            catch (Exception e)
            {
                Debug.LogError("Dns.GetHostAddresses error: " + e);
            }
          
        }

        public void SendIcmpPing()
        {
            Profiler.BeginSample("SendIcmpPing");
            if (m_lastTime == DateTime.MinValue || (DateTime.Now - m_lastTime).Seconds > m_pingSendRate)
            {
                try
                {
                    maxRePingNum = 0;
                    StartPing();
                    m_lastTime = DateTime.Now;
                }
                catch (Exception e)
                {
                    Debug.LogError("sendIcmpPing error");
                }
              
            } 
            Profiler.EndSample();
        }
        
        private void StartPing()
        {
            if (_pinger == null)
            {
                if (this.checkpingInteval != -1)
                {
                    TimeTool.Instance.RemoveTimeEvent(this.checkpingInteval);
                }
                this.checkpingInteval =  TimeTool.Instance.CountdownByDuration(0.01f, checkPingStatus);
                _pinger = new Ping(serverIp);
            }
        }

        private void RePing()
        {
            //若产生一次超时，则重新请求ip地址
            UpdateServerIp(serverAddress);
            
            if (maxRePingNum < 2)
            {
                maxRePingNum++;
                m_lastTime = DateTime.Now;
                _pinger = new Ping(serverIp);
            }
            else
            {
                ResidentHandler.Inst.GetFunction("ClientAddPing").Action(3000);
                _pinger.DestroyPing();
                _pinger = null;
            }
        }
        
        private void checkPingStatus()
        {
            if ((DateTime.Now - m_lastTime).Seconds > overTime && _pinger != null && !_pinger.isDone)//超时五秒删除
            {
                _pinger.DestroyPing();
                RePing();
            }
            if (_pinger!=null && _pinger.isDone)
            {
                ResidentHandler.Inst.GetFunction("ClientAddPing").Action(_pinger.time);
                _pinger.DestroyPing();
                _pinger = null;
            }
        }
    }
}
